package com.blumov.fastbox.compra;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.blumov.fastbox.application.services.compra.PedidoService;
import com.blumov.fastbox.application.services.servicelocator.ServiceLocator;
import com.blumov.fastbox.application.services.servicelocator.ServiceLocatorImpl;
import com.blumov.fastbox.domain.model.compra.ItemPedido;
import com.blumov.fastbox.domain.model.compra.PedidoId;
import com.blumov.fastbox.domain.model.producto.Producto;
import com.blumov.fastbox.domain.model.producto.ProductoRepository;
import com.blumov.fastbox.producto.ProductoDTO;


/**
 * This implementation has additional support from the infrastructure, for
 * exposing as an RMI service and for keeping the OR-mapper unit-of-work open
 * during DTO assembly, analogous to the view rendering for web interfaces.
 * 
 * 
 * Accede a las capas de aplicacion y de dominio
 */
public class TerminalClienteFacadeImpl implements TerminalClienteFacade {

	private PedidoService pedidoService;
	private ProductoRepository productoRepository;

	private static Logger logger = Logger.getLogger(TerminalClienteFacadeImpl.class);

	
	public TerminalClienteFacadeImpl() {
		ServiceLocator serviceLocator = new ServiceLocatorImpl();
		this.pedidoService = serviceLocator.getPedidoService();
		this.productoRepository = serviceLocator.getProductoRepository();
	}
	
	public String crearPedido(List<BandejaDTO> bandejasDTO) {
		logger.log(Level.DEBUG, "Creando pedido...");
		final PedidoId pedidoId = this.pedidoService.crear();
		logger.log(Level.INFO, "Se creó un pedido [id = " + pedidoId.idString() + "]");
		this.agregarBandejas(pedidoId, bandejasDTO);
		return pedidoId.idString();
	}
	
	public List<ProductoDTO> obtenerPromocionesVigentes() {
		List<Producto> promocionesVigentes = this.productoRepository.findPromocionesVigentes();
		return this.toProductosDTO(promocionesVigentes);
	}
	
	private List<ProductoDTO> toProductosDTO(List<Producto> productos) {
		List<ProductoDTO> productosDTO = new ArrayList<ProductoDTO>();
		
		for (Producto producto : productos) {
			ProductoDTO productoDTO = new ProductoDTO();
			productoDTO.setCodigo(producto.getCodigo());
			productoDTO.setPrecio(producto.getPrecio());
			productosDTO.add(productoDTO);
		}
		
		return productosDTO;
	}
	
	/**
	 * Agrega las bandejas de un pedido
	 * 
	 * @param pedidoId Pedido al que se agregan las bandejas
	 * @param bandejasDTO Pedido del que se toman las bandejas 
	 */
	private void agregarBandejas(final PedidoId pedidoId, List<BandejaDTO> bandejasDTO) {
		for (int i = 0; i < bandejasDTO.size(); i++) {
			
			/*
			 * Para la primera vez no se crea una bandeja porque los pedidos se crean con una bandeja asociada.
			 */
			if (i > 0) {
				this.pedidoService.agregarBandeja(pedidoId);
			}
			
			BandejaDTO bandejaDTO = bandejasDTO.get(i);
			this.agregarProductos(pedidoId, bandejaDTO);
		}
	}

	/**
	 * Agrega los productos contenidos en una bandeja a un pedido
	 * 
	 * @param pedidoId Pedido de la que se agregan los productos
	 * @param bandejaDTO Bandeja de la que se toman los productos
	 */
	private void agregarProductos(final PedidoId pedidoId, BandejaDTO bandejaDTO) {
		for (ItemPedidoDTO itemPedidoDTO : bandejaDTO.getItems()) {
			Producto producto = productoRepository.find(itemPedidoDTO.getCodigoProducto());
			ItemPedido itemPedido = new ItemPedido();
			itemPedido.setProducto(producto);
			itemPedido.setCantidad(1);	// FIXME
			this.pedidoService.agregarItem(pedidoId, itemPedido);
		}
	}
}
